#include "udp_utils.hpp"
#include <csignal>
#include <atomic>

// 全局变量用于优雅退出主循环
std::atomic<bool> running{true};

/**
 * UDP服务端连续接收并解析消息
 * @param port 监听端口
 */
void udp_receiver(uint16_t port) {
	// 注册Ctrl+C信号优雅退出
	// std::signal(SIGINT, signal_handler);

	socket_t fd = create_udp_socket();
	if (fd == INVALID_SOCKET_VALUE) {
		std::cerr << "[Error] Create socket failed\n";
		return;
	}

	sockaddr_in local = make_sockaddr("0.0.0.0", port);
	if (::bind(fd, reinterpret_cast<sockaddr *>(&local), sizeof(local)) < 0) {
		std::cerr << "[Error] Bind failed\n";
		close(fd);
		return;
	}

	std::cout << "[Info] UDP is running on: " << port << std::endl;

	std::vector<uint8_t> buf(2048); // 缓冲区，最大支持约2KB消息

	while (running) {
		sockaddr_in src_addr{};
		socklen_t src_len = sizeof(src_addr);

		// 阻塞式接收消息
		ssize_t n = recvfrom(fd, buf.data(), buf.size(), 0, reinterpret_cast<sockaddr *>(&src_addr), &src_len);

		if (n <= 0) {
			if (!running) break; // Ctrl+C时退出
			std::cerr << "[Warning] recvfrom error or empty packet\n";
			continue;
		}

		try {
			// 反序列化协议消息
			Message msg = Message::unpack(buf.data(), n);
			auto &m     = msg.header.magic;

			char src_ip[INET_ADDRSTRLEN] = {};
			inet_ntop(AF_INET, &src_addr.sin_addr, src_ip, sizeof(src_ip));
			std::cout << "\n[Recv] From " << src_ip << ":" << ntohs(src_addr.sin_port) << " | cmd=" << int(m.cmd()) << " flag=" << int(m.flag()) << " routed=" << m.routed()
			          << " payload=[" << std::string(msg.payload.begin(), msg.payload.end()) << "]\n";

			if (m.routed()) {
				for (size_t i = 0; i < msg.routers.size(); ++i) {
					char ipbuf[INET_ADDRSTRLEN] = {};
					inet_ntop(AF_INET, &msg.routers[i].ip, ipbuf, sizeof(ipbuf));
					std::cout << "  Router[" << i << "]: " << ipbuf << ":" << ntohs(msg.routers[i].port) << "\n";
				}
			}
		} catch (const std::exception &ex) {
			std::cerr << "[Error] Parse message failed: " << ex.what() << "\n";
		}
	}

	std::cout << "[Info] UDP server exited...\n";
	close(fd);
}
